<?php
/**
 * customer后台，推荐商品的处理
 * Author: lyun
 * Date: 2019/4/2
 * Created by Panxsoft.
 */

namespace App\Http\Controllers\Service\Customer;

use App\Models\Customer\CustomerRelateHmSkin;
use App\Models\Customer\CustomerRelateSkinProductable;
use App\Models\Customer\CustomerRelateWaxSkin;
use App\Models\Panx\Product;
use App\Services\Utils\PanxCollection;
use App\Services\Utils\Transaction;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;

class RecommendProductService
{
    const CUSTOMER_RELATE_WAX_SKIN_ID_DEFAULT = 0;
    const CUSTOMER_RELATE_HM_SKIN_ID_DEFAULT = 0;
    const STORE_ID_DEFAULT = 0; // 客户自己的store_id值

    /**
     * @param $customer_id
     * @param $skin_type
     * @param int $store_id
     * @return array|Collection
     */
    public function getSkinRelateRecommendProducts($customer_id, $skin_type, $store_id = self::STORE_ID_DEFAULT)
    {
        if ($skin_type === class_basename(CustomerRelateWaxSkin::class)) {
            $customer_skin_item_levels = $this->getWaxCustomerSkinItemLevels($customer_id, $store_id);
        } else {
            $customer_skin_item_levels = $this->getHmCustomerSkinItemLevels($customer_id, $store_id);
        }

        return $customer_skin_item_levels;
    }

    /**
     * @param $customer_id
     * @param $store_id
     * @return mixed
     */
    public function getWaxCustomerSkinItemLevels($customer_id, $store_id)
    {
        $customer_relate_wax_skins = CustomerRelateWaxSkin::where(compact('customer_id'))
            ->where(compact('store_id'))
            ->has('products')
            ->with('products.thumbImage')
            ->orderBy('item_id')
            ->orderBy('level_sort')
            ->get();
        $panx_customer_relate_wax_skin = CustomerRelateWaxSkin::getPanxCustomerRelateWaxSkins();

        $customer_relate_wax_skins->transform(function(CustomerRelateWaxSkin $customer_relate_wax_skin) use($panx_customer_relate_wax_skin){
            $customer_relate_wax_skin->item_name = trans('admin.wax_itemsid_'.$customer_relate_wax_skin->item_id);

            $panx_wax_suggest = $panx_customer_relate_wax_skin->where('level_sort', $customer_relate_wax_skin->level_sort)
                ->where('item_id', $customer_relate_wax_skin->item_id)
                ->first();
            $customer_relate_wax_skin->level_name = $panx_wax_suggest->waxSuggestByLanguage->level_name ?? null;

            $this->getProductThumbImage($customer_relate_wax_skin->products);

            return $customer_relate_wax_skin;
        });

        return $customer_relate_wax_skins;
    }

    /**
     * @param $customer_id
     * @param $store_id
     * @return mixed
     */
    public function getHmCustomerSkinItemLevels($customer_id, $store_id)
    {
        $customer_relate_hm_skins = CustomerRelateHmSkin::where(compact('customer_id'))
            ->where(compact('store_id'))
            ->has('products')
            ->with('products.thumbImage')
            ->orderBy('position_id')
            ->orderBy('detection_type_id')
            ->orderBy('level_sort')
            ->get();
        $panx_customer_relate_hm_skin = CustomerRelateHmSkin::getPanxCustomerRelateHmSkins();

        $customer_relate_hm_skins->transform(function(CustomerRelateHmSkin $customer_relate_hm_skin) use($panx_customer_relate_hm_skin){

            $customer_relate_hm_skin->position_name = trans('admin.hm_position_'.$customer_relate_hm_skin->position_id);
            $customer_relate_hm_skin->item_id = $customer_relate_hm_skin->detection_type_id;
            $customer_relate_hm_skin->item_name = trans('admin.hm_itemsid_'.$customer_relate_hm_skin->detection_type_id);

            $panx_hm_suggest = $panx_customer_relate_hm_skin->where('level_sort', $customer_relate_hm_skin->level_sort)
                ->where('detection_type_id', $customer_relate_hm_skin->detection_type_id)
                ->where('position_id', $customer_relate_hm_skin->position_id)
                ->first();
            $customer_relate_hm_skin->level_name = $panx_hm_suggest->hmSuggestByLanguage->title ?? null;

            $this->getProductThumbImage($customer_relate_hm_skin->products);

            return $customer_relate_hm_skin;
        });

        return $customer_relate_hm_skins;
    }

    /**
     * @param Collection $products
     */
    public function getProductThumbImage(Collection $products)
    {
        (new PanxCollection($products))
            ->eachAppend(['thumb_url'])
            ->makeHidden(['thumbImage']);
    }

    /**
     * @param $products
     * @param $wax_skin
     * @param $customer_id
     * @param int $store_id
     * @return mixed
     * @throws \Exception
     */
    public function storeWaxCustomerSkinItemLevel($products, $wax_skin, $customer_id, $store_id = self::STORE_ID_DEFAULT)
    {
        $item_id = $wax_skin['item_id'];
        $level_sort = $wax_skin['level_sort'];


        $stored = Transaction::handle(function() use($customer_id, $item_id, $level_sort, $products, $store_id){
            /** @var CustomerRelateWaxSkin $customer_relate_wax_skin */
            $customer_relate_wax_skin = (new CustomerRelateWaxSkin)->updateOrCreate([
                'customer_id' => $customer_id,
                'store_id'    => $store_id,
                'item_id'     => $item_id,
                'level_sort'  => $level_sort
            ]);
            $this->updateCustomerRelateSkinProduct($customer_relate_wax_skin, $products);

            return $customer_relate_wax_skin;
        });

        return $stored;
    }

    /**
     * @param $products
     * @param $hm_skin
     * @param $customer_id
     * @param int $store_id
     * @return mixed
     * @throws \Exception
     */
    public function storeHmCustomerSkinItemLevel($products, $hm_skin, $customer_id, $store_id = self::STORE_ID_DEFAULT)
    {
        $position_id = $hm_skin['position_id'];
        $item_id = $hm_skin['item_id'];
        $level_sort = $hm_skin['level_sort'];

        $stored = Transaction::handle(function() use($customer_id, $item_id, $level_sort, $position_id, $products, $store_id){
            /** @var CustomerRelateHmSkin $customer_relate_hm_skin */
            $customer_relate_hm_skin = (new CustomerRelateHmSkin)->updateOrCreate([
                'customer_id'       => $customer_id,
                'store_id'          => $store_id,
                'position_id'       => $position_id,
                'detection_type_id' => $item_id,
                'level_sort'        => $level_sort
            ]);
            $this->updateCustomerRelateSkinProduct($customer_relate_hm_skin, $products);

            return $customer_relate_hm_skin;
        });

        return $stored;
    }

    /**
     * @param Model|CustomerRelateWaxSkin|CustomerRelateHmSkin $customer_relate_skin
     * @param $product_ids
     * @return mixed
     */
    public function updateCustomerRelateSkinProduct(Model $customer_relate_skin, $product_ids)
    {
        $data = [];
        foreach($product_ids as $product_id)
        {
            $data[$product_id] = [
                'productable_id'   => $customer_relate_skin->id,
                'productable_type' => class_basename($customer_relate_skin),
            ];
        }
        $updated = $customer_relate_skin->products()->sync($data);

        return $updated;
    }
}